package com.example.extra.filter;

import com.example.extra.common.Constants;
import com.example.extra.dto.LoginRequestDTO;
import com.example.extra.enums.ErrorEnum;
import com.example.extra.exception.BizException;
import com.example.extra.request.CachedBodyHttpServletRequest;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.filter.OncePerRequestFilter;
import java.io.IOException;


@Slf4j
@Component
public class CaptchaFilter extends OncePerRequestFilter {

    @Autowired
    private  RedisTemplate<String, String> redisTemplate;

    @Autowired
    @Lazy
    private  AuthenticationFailureHandler failureHandler; // 用于处理认证失败


    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {


        // 只拦截登录请求
        if ("/api/auth/login".equals(request.getServletPath()) && "POST".equalsIgnoreCase(request.getMethod())) {
            try {

                // 使用自定义的RequestWrapper来缓存请求体
                CachedBodyHttpServletRequest cachedBodyHttpServletRequest = new CachedBodyHttpServletRequest(request);
                // 从缓存体中获取JSON字符串
                String body = new String(cachedBodyHttpServletRequest.getCachedBody());
                // 从请求中获取验证码参数 (假设是JSON或表单数据)
                ObjectMapper objectMapper = new ObjectMapper();
                LoginRequestDTO loginRequest = objectMapper.readValue(body, LoginRequestDTO.class);
                String captchaKey = loginRequest.getUuid();
                String captchaCode = loginRequest.getCode();

                String redisKey = Constants.REDIS_CAPTCHA_PREFIX + captchaKey;
                String storedCode = redisTemplate.opsForValue().get(redisKey);

                if (!StringUtils.hasText(storedCode)) {
                    throw new BizException(ErrorEnum.BAD_REQUEST.getCode(),"验证码已过期");
                }
                if (!storedCode.equals(captchaCode.toLowerCase())) {
                    throw new BizException(ErrorEnum.BAD_REQUEST.getCode(),"验证码错误");
                }

                // 验证通过，删除Redis中的验证码
                //redisTemplate.delete(redisKey);
                // 继续执行后续过滤器
                filterChain.doFilter(cachedBodyHttpServletRequest, response);
            } catch (BizException e) {
                // 交给认证失败处理器处理
                failureHandler.onAuthenticationFailure(request, response, new BadCredentialsException(e.getMessage()));
            }
        } else {
            filterChain.doFilter(request, response);
        }
    }

}
